#include <cstddef>
#include <iostream>
#include <pthread.h>
#include <unistd.h>
#include <vector>
#include <semaphore.h>
using namespace std;
class RingQueue {
public:
    RingQueue(int capacity)
    :count(capacity), buffer(capacity), front(0), rear(0), size(0) {
        pthread_mutex_init(&mutex, NULL);
        sem_init(&sem_empty, 0, capacity);
        sem_init(&sem_full, 0, 0);
    }
    void Push(int val) {
        sem_wait(&sem_empty);
        pthread_mutex_lock(&mutex);
        buffer[rear] = val;
        rear = (rear + 1) % count;
        size++;
        pthread_mutex_unlock(&mutex);
        sem_post(&sem_full);
    }
    int Pop() {
        sem_wait(&sem_full);
        pthread_mutex_lock(&mutex);
        int val = buffer[front];
        front = (front + 1) % count;
        size--;
        pthread_mutex_unlock(&mutex);
        sem_post(&sem_empty);
        return val;
    }
private:
    int count;
    std::vector<int> buffer;
    int front, rear, size;
    pthread_mutex_t mutex;
    sem_t sem_empty;
    sem_t sem_full;
};
RingQueue rq(10);
void* producer(void* arg) {
    int value = 0;
    while (1) {
        cout << "生产：" << value << endl;
        rq.Push(value++);
        sleep(1);
    }
    return nullptr;
}
void* consumer(void* arg) {
    while (1) {
        int val = rq.Pop();
        cout << "消费：" << val << endl;
        sleep(3);
    }
}
int main() {
    pthread_t p, c;
    pthread_create(&p, NULL, producer, NULL);
    pthread_create(&c, NULL, consumer, NULL);
    pthread_join(p, nullptr);
    pthread_join(c, nullptr);
    return 0;
}